const TeaModel = require('../models/tea')
const StuModel = require('../models/stu')
const ExamModel = require('../models/exam')
const QueBankModel = require('../models/queBank')
const TextPaperModel = require('../models/textPaper')
const IntegratedExamModel = require('../models/IntegratedExam')
const FavoritesModel = require('../models/favorites')
const CollentTopicModel = require('../models/collectTopic')
const RandomDivisionModel = require('../models/randomDivision')
const bcrypt = require('bcryptjs')
const createToken = require('../utils/jwt').createToken
const verifyToken = require('../utils/jwt').verifyToken
const path = require('path');
const fs = require('fs');
const xlsx = require('node-xlsx');


// 设计用户的表模型
const mongoose = require('mongoose')
const Schema = mongoose.Schema
// 考试成绩表结构
const examScoreSchema = new Schema({
    examName: {
        type: String,
        require: true
    },
    examPaper: {
        type: String,
        require: true
    },
    subject: {
        type: String,
        require: true
    },
    account: {
        type: String,
        require: true
    },
    username: {
        type: String,
        require: true
    },
    choiceAnsList: {
        type: String,
        require: true
    },
    judgeAnsList: {
        type: String,
        require: true
    },
    fillBlankAnsList: {
        type: String,
        require: true
    },
    comprehensiveAnsList: {
        type: String,
        require: true
    },
    score: {
        type: String,
        require: true
    },
    classes: {
        type: String,
        require: true
    },
})

module.exports = {
    // 登录
    async login(ctx, next) {
        let { account, password, vertify, code } = ctx.request.body
        if (!account || !password) {
            ctx.body = {
                code: 500,
                msg: "账号或密码不能为空",
                data: null
            }
            return
        }
        if (code != vertify) {
            ctx.body = {
                code: 401,
                msg: '验证码错误！'
            }
            return
        }
        const tea = await TeaModel.findOne({ account })
        const stu = await StuModel.findOne({ account })
        if (tea || stu) {
            const user = tea?tea:stu
            if (await bcrypt.compare(password, user.password)) {
                let jwt = createToken({ account: account })
                ctx.body = {
                    msg: '登录成功',
                    code: 200,
                    id: jwt,
                    data: user
                }
            } else {
                ctx.body = {
                    msg: '密码有误',
                    code: 401,
                }
            }
        } else {
            ctx.body = {
                msg: '账号有误',
                code: 401
            }
        }
    },

//超级管理员部分

    // 注册
    async register(ctx, next) {
        // console.log(ctx.request.body);
        for (let i = 0; i < ctx.request.body.length; i++) {
            const salt = bcrypt.genSaltSync(10)// 加密十次
            let { username, IDNum, permission, subject, classes, enrollmentYear } = ctx.request.body[i]
            let IDNumReg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/
            if (!username || !IDNum) {
                ctx.body = {
                    code: 500,
                    msg: "姓名、身份证号不能为空",
                    data: null
                }
                return
            }else if(!IDNumReg.test(IDNum)) {
                ctx.body = {
                    code: 500,
                    msg: "身份证号输入有误",
                    data: null
                }
                return
            }else if (!permission) {
                ctx.body = {
                    code: 500,
                    msg: "请选择用户身份",
                    data: null
                }
                return
            }else if (permission != '学生' && !subject) {
                ctx.body = {
                    code: 500,
                    msg: "请选择教授课程",
                    data: null
                }
                return
            }else if (permission == '学生' && !classes){
                ctx.body = {
                    code: 500,
                    msg: "请输入班级",
                    data: null
                }
                return
            }
            let isnew = {}
            if(permission == '学生'){
                isnew = await StuModel.find({
                    IDNum: IDNum
                })
            }else if(permission == '教师'){
                isnew = await TeaModel.find({
                    IDNum: IDNum
                })
            }
            if (isnew.length) {
                ctx.body = {
                    msg: '该账号已存在',
                    code: 414
                }
                return
            }
            let password = await bcrypt.hash(IDNum.substring(12,18), salt)
            if (enrollmentYear == undefined) {
                enrollmentYear = new Date().getFullYear()
            }

            let account = ''
            if(permission == '学生'){
                let num = await StuModel.find({enrollmentYear})
                if (num != '') {
                    account = String(Number(num[num.length - 1].account) + 1)
                }else {
                    account = '210' + enrollmentYear % 100 + '00001'
                }
            }else if(permission == '教师'){
                let num = await TeaModel.find()
                if (num != '') {
                    account = String(Number(num[num.length - 1].account) + 1)
                }else {
                    account = '220' + enrollmentYear % 100 + '0001'
                }
            }
            let newuser = {
                username,
                IDNum,
                permission,
                password,
                account,
                subject,
                enrollmentYear,
                classes
            }
            console.log(newuser);
            // 存储到数据库
            if(permission == '学生'){
                await StuModel.create(newuser)
                await FavoritesModel.create({
                    account, username,
                    data: JSON.stringify([{label: '语文', children: [], disabled: true}, {label: '数学', children: [], disabled: true}, {label: '英语', children: [], disabled: true}, 
                        {label: '物理', children: [], disabled: true}, {label: '化学', children: [], disabled: true}, {label: '生物', children: [], disabled: true}, 
                        {label: '政治', children: [], disabled: true}, {label: '历史', children: [], disabled: true}, {label: '地理', children: [], disabled: true}, ])
                })
            }else if(permission == '教师'){
                await TeaModel.create(newuser)
            }
            ctx.body = {
                msg: '注册成功',
                code: 200
            }
        }

    },

    //更新题库
    async uploadQueBank(ctx, next) {
        console.log(ctx.request.body);
        for (let i = 0; i < ctx.request.body.length; i++) {
            const { A, B, C, D, topicType, subject, stem, answer, analysis, knowledgePoints } = ctx.request.body[i]
            const queBankList = await QueBankModel.find({})
            let topicNum = '10100001'
            if (queBankList != '') {
                topicNum = String(Number(queBankList[queBankList.length - 1].topicNum) + 1)
            }
            let newTopic = {
                topicNum,
                topicType,
                subject,
                stem,
                answer,
                analysis,
                A,
                B,
                C,
                D,
                knowledgePoints
            }
            await QueBankModel.create(newTopic)
        }
        ctx.body = {
            msg: '创建成功',
            code: 200
        }
        return 
    },

    // 获取学生列表
    async getStudentList(ctx, next) {
        console.log(ctx.request.body);
        let collection = await StuModel.find({[ctx.request.body.searchType]: new RegExp(ctx.request.body.searchData)})
        ctx.body =  {
            stu: collection,
            code: 200
        }
        return 
    },

    // 获取教师列表
    async getTeacherList(ctx, next) {
        console.log(ctx.request.body);
        let collection = await TeaModel.find({[ctx.request.body.searchType]: new RegExp(ctx.request.body.searchData)})
        ctx.body =  {
            tea: collection,
            code: 200
        }
        return 
    },

    // 获取题库列表
    async getQueBank(ctx, next) {
        let collection = await QueBankModel.find({[ctx.request.body.searchType]: new RegExp(ctx.request.body.searchData)})
        ctx.body =  {
            queBank: collection,
            code: 200
        }
    },

    //修改用户数据
    async edit(ctx, next) {
        if (ctx.request.body.account != undefined) {
            let { account, username, permission, subject, classes } = ctx.request.body
            let where_str = {
                account
            }
            let updata_str = {
                username,
                permission,
                subject,
                classes
            }
            if (permission == '学生') {
                await StuModel.updateOne(where_str, updata_str)
            }else {
                await TeaModel.updateOne(where_str, updata_str)
            }
        }else{
            let { topicNum, stem, answer, analysis } = ctx.request.body
            let where_str = {
                topicNum
            }
            let updata_str = {
                stem,
                answer,
                analysis
            }
            await QueBankModel.updateOne(where_str, updata_str)
        }
        
        ctx.body =  {
            msg: "修改成功",
            code: 200
        }
        return
    },

    //删除用户数据
    async del(ctx, next) {
        let { account, permission, topicNum} = ctx.request.body
        if (permission == '学生') {
            await StuModel.remove({account})
        }else if (permission != undefined) {
            await TeaModel.remove({account})
        }else {
            await QueBankModel.remove({topicNum})
        }
        ctx.body =  {
            msg: "删除成功",
            code: 200
        }
        return
    },
    

// 管理员部分

    //创建单科试卷
    async getTopic(ctx, next) {
        let collection = []
        if (ctx.request.body.subject != undefined) {
            collection = await QueBankModel.find({subject: ctx.request.body.subject})
        }else{
            let choiceQue = []
            let judgeQue = []
            let fillBlankQue = []
            let comprehensiveQue = []
            for (let i = 0; i < ctx.request.body.length; i++) {
                if (ctx.request.body[i].topicType == '单选题') {
                    choiceQue = choiceQue.concat(await QueBankModel.find({topicNum: ctx.request.body[i].topicNum}))
                }else if (ctx.request.body[i].topicType == '判断题') {
                    judgeQue = judgeQue.concat(await QueBankModel.find({topicNum: ctx.request.body[i].topicNum}))
                }else if (ctx.request.body[i].topicType == '填空题') {
                    fillBlankQue = fillBlankQue.concat(await QueBankModel.find({topicNum: ctx.request.body[i].topicNum}))
                }else if (ctx.request.body[i].topicType == '综合题') {
                    comprehensiveQue = comprehensiveQue.concat(await QueBankModel.find({topicNum: ctx.request.body[i].topicNum}))
                }
            }
            collection = {choiceQue, judgeQue, fillBlankQue, comprehensiveQue}
        }
        ctx.body =  {
            topic: collection,
            code: 200
        }
        return
    },
    async createTextPaper(ctx, next) {
        // console.log(ctx.request.body);
        const { choiceQue, judgeQue, fillBlankQue, comprehensiveQue } = ctx.request.body.topicData
        const { choiceScore, judgeScore, fillBlankScore, comprehensiveScore } = ctx.request.body.topicScore
        const { textPaperName, subject } = ctx.request.body.GTPForm
        if (await TextPaperModel.find({textPaperName}) != '') {
            ctx.body = {
                msg: '该试卷已存在',
                code: 414
            }
            return 
        }
        let createTime = new Date()
        let topicNumList = []
        let topicScoreList = []
        for (let i = 0; i < choiceQue.length; i++) {
            topicNumList += choiceQue[i].topicNum + ' '
            topicScoreList += choiceScore[i] + ' '
        }
        for (let i = 0; i < judgeQue.length; i++) {
            topicNumList += judgeQue[i].topicNum + ' '
            topicScoreList += judgeScore[i] + ' '
        }
        for (let i = 0; i < fillBlankQue.length; i++) {
            topicNumList += fillBlankQue[i].topicNum + ' '
            topicScoreList += fillBlankScore[i] + ' '
        }
        for (let i = 0; i < comprehensiveQue.length; i++) {
            topicNumList += comprehensiveQue[i].topicNum + ' '
            topicScoreList += comprehensiveScore[i] + ' '
        }
        console.log(topicNumList, topicScoreList);
        await TextPaperModel.create({
            topicNumList,
            topicScoreList,
            textPaperName,
            subject,
            createTime,
        })
        ctx.body = {
            msg: '创建成功',
            code: 200
        }
        return 
    },

    // 创建考试
    async getTextPaper(ctx, next) {
        const textPaperName =  await TextPaperModel.distinct('textPaperName')
        ctx.body =  {
            textPaperName,
            code: 200
        }
        return
    },
    async releaseExam(ctx, next) {
        // console.log(ctx.request.body);
        let { examName, examDate, examTime, examPaper} = ctx.request.body
        if (await ExamModel.find({examName}) != '') {
            ctx.body = {
                msg: '该考试已存在',
                code: 414
            }
            return 
        }
        let textPaper = await TextPaperModel.find({textPaperName: examPaper})
        let newexam = {
            examName,
            examStart: examDate[0],
            examEnd: examDate[1],
            examTime,
            examPaper,
            subject: textPaper[0].subject,
        }
        console.log(newexam);
        await ExamModel.create(newexam)
        ctx.body = {
            msg: '创建成功',
            code: 200
        }
        return 
    },

    //整合考试
    async getClasses(ctx, next) {
        const classes =  await StuModel.distinct('classes')
        const enrollmentYear =  await StuModel.distinct('enrollmentYear')
        ctx.body =  {
            classes: classes,
            enrollmentYear: enrollmentYear,
            code: 200
        }
        return
    },
    async getTeacher(ctx, next) {
        let optionTea = []
        const subject =  await TeaModel.distinct('subject')
        for (let i = 0; i < subject.length; i++) {
            const Tea = await TeaModel.find({ subject: subject[i] })
            let children = []
            for (let j = 0; j < Tea.length; j++) {
                children.push({
                    value: Tea[j].account,
                    label: Tea[j].username,
                })
            }
            optionTea.push({
                value: subject[i],
                label: subject[i],
                children
            })
        }
        ctx.body = {
            optionTea,
            code: 200
        }
        return
    },
    async createExamFile(ctx, next) {
        const { examFileName, examStu, examFileExplain, examTea } = ctx.request.body
        if (await IntegratedExamModel.find({examFileName}) != '') {
            ctx.body = {
                msg: '试卷文件已存在',
                code: 414
            }
            return 
        }
        let examClasses = ''
        let allStu = []
        for (let i = 0; i < examStu.length; i++) {
            examClasses += examStu[i][1] + ' '
            allStu = allStu.concat(await StuModel.find({ classes: examStu[i][1] }).distinct('account'))
        }
        await IntegratedExamModel.create({
            examFileName,
            examClasses,
            examFileExplain,
            examTea: JSON.stringify(examTea)
        })
        let subject = ['语文', '数学', '英语', '物理', '化学', '生物', '政治', '历史', '地理']
        for (let i = 0; i < subject.length; i++) {
            allStu.sort(function () {
                return Math.random() - 0.5;
            });          
            let accountList = []
            let num = 0
            for (let j = 0; j < examTea.length; j++) { 
                if (examTea[j][0] == subject[i]) { 
                    num += 1 
                    accountList.push(examTea[j][1])
                } 
            }   
            for (let j = 0; j < num; j++) {
                await RandomDivisionModel.create({
                    examFileName,
                    account: accountList[j],
                    subject: subject[i],
                    stuList: JSON.stringify(allStu.slice(j * allStu.length / num, (j + 1) * allStu.length / num)),
                    isFinish: 'false'
                })
            }
        }
        // 通过 mongoose.model 往数据库里面映射出一张User表
        module.exports = mongoose.model(examFileName, examScoreSchema)

        ctx.body = {
            msg: '创建成功',
            code: 200
        }
        return
    },
    async getExamFile(ctx, next) {
        const examFile = await IntegratedExamModel.find()
        const Exam = await ExamModel.find()
        let examFileName = []
        let examInf = []
        let examList = []
        let classesList = []
        for (let i = 0; i < examFile.length; i++) {
            examFileName.push(examFile[i].examFileName)
            classesList.push(examFile[i].examClasses)
            if (examFile[i].examList != undefined) {
                examList.push(examFile[i].examList.split(' '))
            }
        }
        for (let i = 0; i < Exam.length; i++) {
            examInf.push({
                examName: Exam[i].examName,
                subject: Exam[i].subject,
            })
        }
        ctx.body = {
            classesList,
            examList,
            examFileName,
            examInf,
            code: 200
        }
        return 
    },
    async editExamFile(ctx, next) {
        // console.log(ctx.request.body);
        let examList = ''
        let { examFileName, subject, exam } = ctx.request.body
        if (examFileName == '') {
            ctx.body = {
                msg: '请选择考试文件',
                code: 500
            }
            return 
        }else if(subject == '') {
            ctx.body = {
                msg: '请选择课目',
                code: 500
            }
            return
        }else if (subject.length != exam.length){
            ctx.body = {
                msg: '请选择各个课目考试',
                code: 500
            }
            return
        }
        console.log(exam, subject);
        for (let i = 0; i < exam.length; i++) {
            examList += exam[i] + ' '
        }
        await IntegratedExamModel.updateOne({examFileName}, {examList})
        for (let i = 0; i < subject.length; i++) {
            await RandomDivisionModel.updateMany({ subject: subject[i], examFileName }, {examName: exam[i]})
        }
        ctx.body = {
            msg: '修改成功',
            code: 200
        }
        return 
    },

// 教师部分
    // 创建试题
    async createTopic(ctx, next) {
        const { A, B, C, D, topicType, subject, stem, answer, analysis, knowledgePoints } = ctx.request.body
        const queBankList = await QueBankModel.find({})
        let topicNum = '0100001'
        if (queBankList != '') {
            topicNum = String(Number(queBankList[queBankList.length - 1].topicNum) + 1)
        }
        let newTopic = {
            topicNum,
            topicType,
            subject,
            stem,
            answer,
            analysis,
            A,
            B,
            C,
            D,
            knowledgePoints
        }
        await QueBankModel.create(newTopic)
        ctx.body = {
            msg: '创建成功',
            code: 200
        }

    },

    // 自动改卷
    async automaticCorrectPapers(ctx, next) {
        let score = 0

        let { examFileName, examName, account, partialScore, isFinish, teaAccount } = ctx.request.body
        let answerSheet = await mongoose.model(examFileName, examScoreSchema).findOne({ account, examName })
        let choiceAnsList = []
        if (answerSheet.choiceAnsList != null) { choiceAnsList = answerSheet.choiceAnsList.split(' ') }
        let judgeAnsList = []
        if (answerSheet.judgeAnsList != null) { judgeAnsList = answerSheet.judgeAnsList.split(' ') }

        let textPaper = await TextPaperModel.findOne({ textPaperName: (await ExamModel.findOne({ examName })).examPaper })
        let topicNumList = textPaper.topicNumList.split(' ')
        let topicScoreList = textPaper.topicScoreList.split(' ')

        for (let i = 0; i < topicNumList.length - 1; i++) {
            let topic = await QueBankModel.findOne({ topicNum: topicNumList[i] })
            if (topic.topicType == '单选题' && choiceAnsList[i] == topic.answer) { 
                score  +=  Number(topicScoreList[i])
            }else if (topic.topicType == '判断题' && judgeAnsList[i] == topic.answer) {
                score  += Number(topicScoreList[i])
            }
        }
        if (partialScore != undefined) { score += partialScore }
        await mongoose.model(examFileName, examScoreSchema).updateOne({
            account, username: answerSheet.username, examName, examPaper: answerSheet.examPaper
        }, { score })
        if (isFinish) {
            await RandomDivisionModel.updateOne({ account: teaAccount, examFileName }, {isFinish})
        }
        ctx.body = {
            msg: '已提交',
            code: 200,
        }
        return
    },

    // 获取待批改试卷列表
    async getMarkTextPaperInf(ctx, next) {
        let MTP = await RandomDivisionModel.find({ account: ctx.request.body.account })
        let MTPList = []
        for (let i = 0; i < MTP.length; i++) {
            if (MTP[i].isFinish != 'true') {
                MTPList.push({
                    examFileName: MTP[i].examFileName,
                    examName: MTP[i].examName,
                    subject: MTP[i].subject,
                    surplusNum: JSON.parse(MTP[i].stuList).length,
                    startTime: (await ExamModel.findOne({ examName: MTP[i].examName })).examEnd,
                })
            }
           
        }
        ctx.body = {
            MTPList,
            code: 200,
        }
        return
    },

    // 教师改卷
    async getAnswerSheet(ctx, next) {
        let stuList = JSON.parse((await RandomDivisionModel.findOne(ctx.request.body)).stuList)
        let examInf = await ExamModel.findOne({ examName: ctx.request.body.examName })
        let answerSheetList = []
        for (let i = 0; i < stuList.length; i++) {
            let answerSheet = await mongoose.model(ctx.request.body.examFileName, examScoreSchema).findOne({
                account: stuList[i], examName: ctx.request.body.examName
            })
            let stu = await StuModel.findOne({ account: stuList[i] })
            if (answerSheet == null) {
                await mongoose.model(ctx.request.body.examFileName, examScoreSchema).create({
                    account: stuList[i],
                    username: stu.username,
                    classes: stu.classes,
                    examName: ctx.request.body.examName, 
                    examFileName: ctx.request.body.examFileName,
                    examPaper: examInf.examPaper, 
                    choiceAnsList: '', 
                    judgeAnsList: '',
                    fillBlankAnsList: '',
                    comprehensiveAnsList: '', 
                    subject: examInf.subject, 
                    score: 0
                })
            }else if (answerSheet.score == -1) {
                answerSheetList.push({
                    account: answerSheet.account,
                    username: answerSheet.username,
                    fillBlankAnsList: answerSheet.fillBlankAnsList.split(' '),
                    comprehensiveAnsList: answerSheet.comprehensiveAnsList.split(' '),
                })
            }
        }
        let textPaper = await TextPaperModel.findOne({ textPaperName: examInf.examPaper })
        let topicNumList = textPaper.topicNumList.split(' ')
        let topicScoreList = textPaper.topicScoreList.split(' ')
        let fillBlankList = []
        let comprehensiveList = []
        let fillBlankScoreList = []
        let comprehensiveScoreList = []
        for (let i = 0; i < topicNumList.length - 1; i++) { 
            let topic = await QueBankModel.findOne({ topicNum: topicNumList[i] })
            if (topic.topicType == '填空题') { 
                fillBlankList.push(topic) 
                fillBlankScoreList.push(topicScoreList[i])
            }
            else if (topic.topicType == '综合题') { 
                comprehensiveList.push(topic) 
                comprehensiveScoreList.push(topicScoreList[i])
            }
        }
        if (answerSheetList.length == 0) {
            await RandomDivisionModel.updateOne({ 
                account: ctx.request.body.account, 
                examName: ctx.request.body.examName,
                examFileName: ctx.request.body.examFileName,
            }, {isFinish: 'true'})
        }
        ctx.body = {
            fillBlankList,
            fillBlankScoreList,
            comprehensiveList,
            comprehensiveScoreList,
            answerSheetList,
            code: 200,
        }
        return
    },

    // 获取学科成绩表信息
    async getexamInf(ctx, next) {
        let { textPaper, examFileName, classesList } = ctx.request.body
        
        let examInfList = []
        for (let i = 0; i < textPaper.length; i++) {
            let examInf = []
            for (let j = 0; j < textPaper[i].length - 1; j++) {
                let TP = await ExamModel.findOne({ examName: textPaper[i][j] })
                let completedNum = (await mongoose.model(examFileName[i], examScoreSchema).find({ examName: TP.examName })).length
                examInf.push({
                    subject: TP.subject,
                    examFileName: examFileName[i],
                    examName: TP.examName,
                    completedNum
                })
            }
            let totalNum = 0
            classesList[i] = classesList[i].split(' ')
            for (let j = 0; j < classesList[i].length - 1; j++) {
                totalNum += (await StuModel.find({classes: classesList[i][j]})).length
            }
            examInfList.push({ examInf, totalNum })
        }
        ctx.body = {
            examInfList,
            code: 200,
        }
        return
    },

    // 获取学科成绩（包括排序）
    async getSubjectScoreTable(ctx, next) {
        let SST = await mongoose.model(ctx.request.body.examFileName, examScoreSchema).find({ examName: ctx.request.body.examName })
        let SSTList = []
        for (let i = 0; i < SST.length; i++) {
            SSTList.push({
                account: SST[i].account,
                username: SST[i].username,
                classes: SST[i].classes,
                classes: SST[i].classes,
                score: SST[i].score,
                subject: SST[i].subject,
                examName: SST[i].examName,
            })
        }
        ctx.body = {
            SSTList: SSTList.sort((a, b) => b.score == a.score ? a.account - b.account : b.score - a.score),
            code: 200
        }
        return
    },

    // 检测考试是否批改完成(通过表中人数判断)
    async getAllExamInf(ctx, next) {
        let { examFileName, classesList, examList } = ctx.request.body
        let canView = []
        for (let i = 0; i < examFileName.length; i++) {
            let completedNum = (await mongoose.model(examFileName[i], examScoreSchema).find()).length

            let totalNum = 0
            classesList[i] = classesList[i].split(' ')
            for (let j = 0; j < classesList[i].length - 1; j++) {
                totalNum += (await StuModel.find({classes: classesList[i][j]})).length
            }
            totalNum *= (examList[i].length - 1)
            if (completedNum != totalNum) { canView.push('flase') }
            else { canView.push('true') }
        }
        ctx.body = {
            canView,
            code: 200,
        }
        return
    },

    // 获取考试文件总成绩（包括排序）
    async getTotalScoreTable(ctx, next) {
        let classesList = (await IntegratedExamModel.findOne(ctx.request.body)).examClasses.split(' ')
        let TSTList = []
        for (let i = 0; i < classesList.length - 1; i++) {
            let stu = await StuModel.find({ classes:classesList[i] })
            for (let j = 0; j < stu.length; j++) {
                let TST = {
                    account: stu[j].account,
                    username: stu[j].username,
                    classes: classesList[i],
                    scoreList: [],
                    totalScore: 0,
                }
                let scoreList = await mongoose.model(ctx.request.body.examFileName, examScoreSchema).find({ account: stu[j].account })
                for (let k = 0; k < scoreList.length; k++) {
                    TST.scoreList.push({
                        subject: scoreList[k].subject,
                        score: scoreList[k].score,
                    })
                    TST.totalScore += Number(scoreList[k].score) 
                }
                TSTList.push(TST)
            }
        }
        ctx.body = {
            TSTList: TSTList.sort((a, b) => b.totalScore == a.totalScore ? a.account - b.account : b.totalScore - a.totalScore),
            classesList,
            code: 200
        }
        return
    },

// 学生部分

    // 获取未开始考试文件
    async getStuExamFile(ctx, next){
        let { classes, account, username } = ctx.request.body
        let examFileList = await IntegratedExamModel.find({
            examClasses: new RegExp(classes)
        })
        let examList = []
        let nextExamEndList = []
        for (let i = 0; i < examFileList.length; i++) {
            let examListInf = examFileList[i].examList.split(' ')
            let exam = []
            let nextExamEnd = new Date(9999, 1, 1)
            for (let j = 0; j < examListInf.length - 1; j++) {
                if (await mongoose.model(examFileList[i].examFileName, examScoreSchema).findOne({ 
                    account: account, username: username, examName:  examListInf[j] 
                }) == null) {
                    let examInf = await ExamModel.findOne({ examName: new RegExp(examListInf[j]) })
                    // 检测学生过期考试
                    if (new Date() > new Date(examInf.examEnd)) {
                        await mongoose.model(examFileList[i].examFileName, examScoreSchema).create({
                            account, username, 
                            examName: examInf.examName, 
                            examPaper: examInf.examPaper, 
                            examFileName: examFileList[i].examFileName,
                            choiceAnsList: '', 
                            judgeAnsList: '',
                            fillBlankAnsList: '',
                            comprehensiveAnsList: '', 
                            subject: examInf.subject, 
                            score: 0
                        })
                    }else{
                        if (new Date(nextExamEnd) > new Date(examInf.examEnd)) { nextExamEnd = examInf.examEnd }
                        exam = exam.concat(examInf)
                    }
                }
            }
            examList.push(exam)
            nextExamEndList.push(nextExamEnd)
        }
        ctx.body = {
            examFileList,
            examList,
            nextExamEndList,
            code: 200
        }
    },

    // 获取考试试卷
    async getExamPaper(ctx, next) {
        let examInf = await ExamModel.findOne({
            examName: ctx.request.body.examName,
            examPaper: ctx.request.body.examPaper
        })
        let textPaperInf = await TextPaperModel.findOne({
            textPaperName: examInf.examPaper
        })
        let topicNumList = textPaperInf.topicNumList.split(' ')
        let topicScoreList = textPaperInf.topicScoreList.split(' ')
        let choiceQue = []
        let judgeQue = []
        let fillBlankQue = []
        let comprehensiveQue = []
        for (let i = 0; i < topicNumList.length - 1; i++) {
            let {topicType, stem, A, B, C, D} = await QueBankModel.findOne({topicNum: topicNumList[i]})
            if (topicType == '单选题') {
                choiceQue = choiceQue.concat({
                    topicScore: topicScoreList[i],
                    topicType, stem, A, B, C, D
                })
            }else if (topicType == '判断题') {
                judgeQue = judgeQue.concat({
                    topicScore: topicScoreList[i],
                    topicType, stem, A, B, C, D
                })
            }else if (topicType == '填空题') {
                fillBlankQue = fillBlankQue.concat({
                    topicScore: topicScoreList[i],
                    topicType, stem, A, B, C, D
                })
            }else if (topicType == '综合题') {
                comprehensiveQue = comprehensiveQue.concat({
                    topicScore: topicScoreList[i],
                    topicType, stem, A, B, C, D
                })
            }
        }
        ctx.body = {
            textPaper: {
                choiceQue,
                judgeQue,
                fillBlankQue,
                comprehensiveQue,
            },
            code: 200
        }
    },

    // 上传答题卡
    async uploadExamInf(ctx, next) {
        // console.log(ctx.request.body);
        let { option, judge, fillBlank, comprehensive, account, username, examName, examPaper, examFileName, subject } = ctx.request.body
        let choiceAnsList = ''
        let judgeAnsList = ''
        let fillBlankAnsList = ''
        let comprehensiveAnsList = ''
        for (let i = 0; i < option.length; i++) { choiceAnsList += option[i] + ' ' }
        for (let i = 0; i < judge.length; i++) { judgeAnsList += judge[i] + ' ' }
        for (let i = 0; i < fillBlank.length; i++) { fillBlankAnsList += fillBlank[i] + ' ' }
        for (let i = 0; i < comprehensive.length; i++) { comprehensiveAnsList += comprehensive[i] + ' ' }

        await mongoose.model(examFileName, examScoreSchema).create({
            account, username, classes: (await StuModel.findOne({ account, username })).classes,
            examName, examPaper, examFileName, 
            choiceAnsList, judgeAnsList, fillBlankAnsList, comprehensiveAnsList, 
            subject, score: -1
        })

        ctx.body = {
            msg: '提交成功',
            code: 200
        }
    },

    // 获取已结束考试文件
    async getCompletedStuExamInf(ctx, next) {
        let { classes, account, username } = ctx.request.body
        let examFileList = await IntegratedExamModel.find({
            examClasses: new RegExp(classes)
        })
        let examList = []
        for (let i = 0; i < examFileList.length; i++) {
            let examListInf = examFileList[i].examList.split(' ')
            let exam = []
            for (let j = 0; j < examListInf.length - 1; j++) {
                let examInf = await mongoose.model(examFileList[i].examFileName, examScoreSchema).findOne({
                    account: account, username: username, examName:  examListInf[j],
                })
                if (examInf != null) { exam = exam.concat(examInf) }
            }
            examList.push(exam)
        }
        ctx.body = {
            examFileList,
            examList,
            code: 200
        }
    },

    // 获取查看考试试卷
    async getViewTextPaper(ctx, next) {
        let { examFileName, examName, examPaper, subject, account, username } = ctx.request.body

        let answerSheet = await mongoose.model(examFileName, examScoreSchema).findOne({ account, username, examName, examPaper, })
        let userChoiceAnsList = answerSheet.choiceAnsList != undefined ? answerSheet.choiceAnsList.split(' ') : ''
        let userJudgeAnsList = answerSheet.judgeAnsList != undefined? answerSheet.judgeAnsList.split(' ') : ''
        let userFillBlankAnsList = answerSheet.fillBlankAnsList != undefined ? answerSheet.fillBlankAnsList.split(' ') : ''
        let userComprehensiveAnsList = answerSheet.comprehensiveAnsList != undefined ? answerSheet.comprehensiveAnsList.split(' ') : ''

        let textPaper = await TextPaperModel.findOne({ textPaperName: examPaper })
        let topicNumList = textPaper.topicNumList.split(' ')
        let topicScoreList = textPaper.topicScoreList.split(' ')

        let choiceTopicList = []
        let judgeTopicList = []
        let fillBlankTopicList = []
        let comprehensiveTopicList = []
        let choiceScoreList = []
        let judgeScoreList = []
        let fillBlankScoreList = []
        let comprehensiveScoreList = []
        for (let i = 0; i < topicNumList.length - 1; i++) {
            let topic = await QueBankModel.findOne({ topicNum: topicNumList[i] })

            if (topic.topicType == '单选题') { 
                choiceTopicList.push(topic) 
                choiceScoreList.push(topicScoreList[i])
            }
            else if (topic.topicType == '判断题') { 
                judgeTopicList.push(topic) 
                judgeScoreList.push(topicScoreList[i])
            }
            else if (topic.topicType == '填空题') { 
                fillBlankTopicList.push(topic) 
                fillBlankScoreList.push(topicScoreList[i])
            }
            else if (topic.topicType == '综合题') {
                comprehensiveTopicList.push(topic) 
                comprehensiveScoreList.push(topicScoreList[i])
            }
        }
        let viewTextPaper = {
            userChoiceAnsList, userJudgeAnsList, userFillBlankAnsList, userComprehensiveAnsList,
            choiceTopicList, judgeTopicList, fillBlankTopicList, comprehensiveTopicList,
            choiceScoreList, judgeScoreList, fillBlankScoreList, comprehensiveScoreList,
        }
        // console.log(viewTextPaper);
        ctx.body = {
            viewTextPaper,
            code: 200
        }
    },

    // 获取收藏夹
    async getCollectionStructure(ctx, next) {
        let { data } =  await FavoritesModel.findOne({ account:ctx.request.body.account, username:ctx.request.body.username })
        ctx.body ={
            data: JSON.parse(data),
            code: 200
        }
    },

    // 创建收藏夹
    async collectionStructure(ctx, next) {
        // console.log(ctx.request.body);
        let { data } = ctx.request.body
        let { account, username } = ctx.request.body.userInf
        let { subject, collectionStructureName } = ctx.request.body.CSForm

        for (let i = 0; i < data.length; i++) {
            if (data[i].label == subject) {
                if (JSON.parse((await FavoritesModel.findOne({ account, username })).data)[i].children.indexOf(collectionStructureName) == -1) {
                    data[i].children.push({ label: collectionStructureName })
                    break
                }else{
                    ctx.body ={
                        msg: '该文件夹以存在',
                        code: 414
                    }
                    return
                }
            } 
        }

        await FavoritesModel.updateOne({ account, username }, { data: JSON.stringify(data) })

        ctx.body ={
            msg: '创建成功',
            code: 200
        }
        return
    },

    // 收藏试题
    async collectTopic(ctx, next) {
        // console.log(ctx.request.body);
        let { topicData, userAns, collectionStructureName } = ctx.request.body
        if (collectionStructureName.length != 2) {
            ctx.body ={
                msg: '选且只选一个文件夹',
                code: 414
            }
            return
        }
        let { account, username } = ctx.request.body.inf
        collectionStructureName = collectionStructureName[0].label + ' ' + collectionStructureName[1].label

        let CTM = await CollentTopicModel.findOne({ collectionStructureName, account, username })
        if (CTM == null) {
            let arr = []
            arr.push({ userAns, topicNum: topicData.topicNum })
            let data = JSON.stringify(arr)
            await CollentTopicModel.create({ collectionStructureName, account, username, data })
        }else{
            let oldData = JSON.parse(CTM.data)
            let arr = []
            for (let i = 0; i < oldData.length; i++) { 
                if (oldData[i].topicNum == topicData.topicNum) {
                    ctx.body ={
                        msg: '该题已在收藏夹中',
                        code: 414
                    }
                    return
                }
                arr.push(oldData[i]) 
            }
            arr.push({ userAns, topicNum: topicData.topicNum })
            let data = JSON.stringify(arr)
            console.log(data);
            await CollentTopicModel.updateOne({ collectionStructureName, account, username }, { collectionStructureName, account, username, data })
        }
        
        ctx.body ={
            msg: '已收藏',
            code: 200
        }
        return
    },

    // 获取所有已收藏试题题号
    async getcollectTopicNum(ctx, next) {
        let { account, username } = ctx.request.body
        let CTM = await CollentTopicModel.find({ account, username })
        let topicNumList = []
        for (let i = 0; i < CTM.length; i++) {
            let data = JSON.parse(CTM[i].data)
            for (let j = 0; j < data.length; j++) {
                topicNumList.push(data[j].topicNum)
            }
        }
        ctx.body = {
            topicNumList,
            code: 200
        }
        return
    },

    // 获取文件夹下已收藏试题
    async getCollectTopic(ctx, next) {
        let CTN = await CollentTopicModel.findOne(ctx.request.body)
        let data = JSON.parse(CTN.data)
        let topicDataList = []
        for (let i = 0; i < data.length; i++) {
            topicDataList.push({
                userAns: data[i].userAns,
                topicData: await QueBankModel.findOne({topicNum: data[i].topicNum})
            })
        }
        ctx.body ={
            topicDataList,
            code: 200
        }
        return
    },

    // 取消收藏
    async cancelCollection(ctx, next){
        console.log(ctx.request.body);
        let CTN = JSON.parse((await CollentTopicModel.findOne(ctx.request.body.viewCollectFileInf)).data)
        let newData = []
        for (let i = 0; i < CTN.length; i++) {
            if (CTN[i].topicNum != ctx.request.body.topicNum) {
                newData.push(CTN[i])
            }
        }
        await CollentTopicModel.updateOne(ctx.request.body.viewCollectFileInf, {data: JSON.stringify(newData)})
        ctx.body ={
            msg: '已取消收藏',
            code: 200
        }
        return
    },

    // 获取所有考试时间
    async getExamTime(ctx, next) {
        let examInf = await ExamModel.find(ctx.request.body)
        let examDateList = []
        for (let i = 0; i < examInf.length; i++) {
            examDateList.push(examInf[i].examStart)
        }
        ctx.body = {
            examDateList,
            code: 200
        }
        return
    },
}